/**
 * created by 小卷毛, 2021-05-29
 * Copyright (c) 2021, 416143467@qq.com All Rights Reserved.
 * #                   *********                            #
 * #                  ************                          #
 * #                  *************                         #
 * #                 **  ***********                        #
 * #                ***  ****** *****                       #
 * #                *** *******   ****                      #
 * #               ***  ********** ****                     #
 * #              ****  *********** ****                    #
 * #            *****   ***********  *****                  #
 * #           ******   *** ********   *****                #
 * #           *****   ***   ********   ******              #
 * #          ******   ***  ***********   ******            #
 * #         ******   **** **************  ******           #
 * #        *******  ********************* *******          #
 * #        *******  ******************************         #
 * #       *******  ****** ***************** *******        #
 * #       *******  ****** ****** *********   ******        #
 * #       *******    **  ******   ******     ******        #
 * #       *******        ******    *****     *****         #
 * #        ******        *****     *****     ****          #
 * #         *****        ****      *****     ***           #
 * #          *****       ***        ***      *             #
 * #            **       ****        ****                   #
 */
package com.rzico.sbl.other

import android.content.Context
import android.graphics.Color
import android.text.InputFilter
import android.text.InputType
import android.text.method.DigitsKeyListener
import android.view.Gravity
import android.view.KeyEvent
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged
import androidx.recyclerview.widget.RecyclerView
import cn.bingoogolapple.qrcode.zxing.QRCodeEncoder
import com.flyco.animation.FadeEnter.FadeEnter
import com.flyco.animation.FadeExit.FadeExit
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.rzico.sbl.R
import com.rzico.sbl.model.CupboardCodeData
import com.rzico.sbl.model.LatLngBean
import com.rzico.sbl.model.MasterData
import com.rzico.sbl.model.OrderData
import com.rzico.sbl.model.OrderLogData
import com.rzico.sbl.model.QRMode
import com.rzico.sbl.model.RegionBean
import com.rzico.sbl.ui.WebActivity
import com.rzico.sbl.ui.order.DeliverDetailActivity
import com.tuyenmonkey.textdecorator.TextDecorator
import com.xinnuo.common.decoration.DividerLRDecoration
import com.xinnuo.common.decoration.SpaceTBDecoration
import com.xinnuo.common.extend.condition
import com.xinnuo.common.extend.conditionElse
import com.xinnuo.common.extend.conditionElseValue
import com.xinnuo.common.extend.conditionIf
import com.xinnuo.common.extend.content
import com.xinnuo.common.extend.find
import com.xinnuo.common.extend.formatDecimal
import com.xinnuo.common.extend.formatDistance
import com.xinnuo.common.extend.getColorEx
import com.xinnuo.common.extend.gone
import com.xinnuo.common.extend.inflate
import com.xinnuo.common.extend.invisibleValue
import com.xinnuo.common.extend.notEmpty
import com.xinnuo.common.extend.oneClick
import com.xinnuo.common.extend.orEmpty
import com.xinnuo.common.extend.startActivityEx
import com.xinnuo.common.extend.textTrim
import com.xinnuo.common.extend.visible
import com.xinnuo.common.extend.visibleValue
import com.xinnuo.common.helper.doubleValue
import com.xinnuo.common.helper.getScreenWidth
import com.xinnuo.common.helper.getString
import com.xinnuo.common.helper.getTimeString
import com.xinnuo.common.helper.intValue
import com.xinnuo.common.helper.phoneReplaceWithStar
import com.xinnuo.common.helper.shortToast
import com.xinnuo.common.helper.toInt
import com.xinnuo.common.other.DecimalNumberFilter
import com.xinnuo.common.other.NameLengthFilter
import com.xinnuo.common_ui.base.BaseDialog
import com.xinnuo.common_ui.base.BasePopup
import com.xinnuo.common_ui.base.BottomDialog
import com.xinnuo.common_ui.base.loadLinear
import com.xinnuo.common_ui.glideExt.loadCircleImage
import com.xinnuo.common_ui.utils.applyFlowableSchedulers
import com.xinnuo.common_ui.utils.clear
import com.xinnuo.loopview.LoopView
import com.xinnuo.slimadapter.SlimAdapter
import com.xinnuo.theme.BuildConfig
import io.reactivex.Flowable

/**
 * 描 述：
 * 作 者：小卷毛  2021-05-29 11:47
 * 修改描述：
 * 修 改 人：
 * 修改版本：
 */

/**
 * 水票输入提示框
 */
fun Context.showTicketDialog(
    name: String,
    title: String = "赠送水票",
    minCount: Int = 1,
    maxCount: Int = 0,
    isForced: Boolean = false,
    onDismiss: () -> Unit = {},
    onSelect: (TextView, Array<Int>) -> Unit = { _, _ -> },
    onCancel: () -> Unit = {},
    onSure: (String, String) -> Unit = { _, _ -> }
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(0.8f)
            val view = inflate<View>(R.layout.dialog_ticket_input)

            val llSelect = view.find<LinearLayout>(R.id.dialog_select)
            val tvTitle = view.find<TextView>(R.id.dialog_title)
            val tvName = view.find<TextView>(R.id.dialog_name)
            val etNum = view.find<EditText>(R.id.dialog_num)
            val etMemo = view.find<EditText>(R.id.dialog_memo)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            tvTitle.text = title
            tvName.text = name
            val mMaxArray = arrayOf(maxCount)

            llSelect.oneClick { onSelect.invoke(tvName, mMaxArray) }

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                val amount = etNum.content

                when {
                    amount.isEmpty() -> {
                        this@showTicketDialog.shortToast("请输入水票数量")
                        return@oneClick
                    }

                    amount.intValue < minCount -> {
                        this@showTicketDialog.shortToast("水票数量不能小于${minCount}张")
                        return@oneClick
                    }

                    mMaxArray[0] > 0 && amount.intValue > mMaxArray[0] -> {
                        this@showTicketDialog.shortToast("水票数量不能超过${mMaxArray[0]}张")
                        return@oneClick
                    }
                }

                dismiss()
                onSure.invoke(amount, etMemo.textTrim)
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        return@setOnKeyListener conditionIf(
            express = keyCode == KeyEvent.KEYCODE_BACK,
            valueT = isForced,
            valueF = false
        )
    }
    dialog.setCanceledOnTouchOutside(!isForced)
    dialog.setOnDismissListener { onDismiss() }
    dialog.show()

    return dialog
}

/**
 * 押桶、借桶输入提示框
 */
fun Context.showBucketDialog(
    name: String,
    type: Int = 1,
    defaultPrice: String = "",
    isForced: Boolean = false,
    onDismiss: () -> Unit = {},
    onSelect: (TextView, Array<Double>) -> Unit = { _, _ -> },
    onCancel: () -> Unit = {},
    onSure: (String, String) -> Unit = { _, _ -> }
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(0.8f)
            val view = inflate<View>(R.layout.dialog_bucket_input)

            val llSelect = view.find<LinearLayout>(R.id.dialog_select)
            val llType = view.find<LinearLayout>(R.id.dialog_type)
            val tvTitle = view.find<TextView>(R.id.dialog_title)
            val tvName = view.find<TextView>(R.id.dialog_name)
            val etNum = view.find<EditText>(R.id.dialog_num)
            val etMemo = view.find<EditText>(R.id.dialog_memo)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            // 设置可输入字符
            // etNum.keyListener = DigitsKeyListener.getInstance("0123456789")

            when (type) {
                1 -> tvTitle.text = "押桶"
                2 -> {
                    tvTitle.text = "借桶"
                    llType.gone()

                    // 设置可输入字符
                    // etNum.keyListener = DigitsKeyListener.getInstance("0123456789-")
                }

                3 -> tvTitle.text = "退桶"
                4 -> {
                    tvTitle.text = "还桶"
                    llType.gone()
                }
            }

            val barrelPriceArr = arrayOf(defaultPrice.doubleValue)

            tvName.text = name
            etMemo.filters = arrayOf<InputFilter>(DecimalNumberFilter())
            etNum.doOnTextChanged { text, _, _, _ ->
                (barrelPriceArr[0] > 0)
                    .condition {
                        etMemo.setText(
                            (text.toInt * barrelPriceArr[0]).formatDecimal()
                        )
                    }
            }

            llSelect.oneClick {
                etNum.clear()
                onSelect.invoke(tvName, barrelPriceArr)
            }

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                val amount = etNum.content
                val totalMoney = etMemo.content

                when {
                    amount.isEmpty() -> {
                        this@showBucketDialog.shortToast("请输入桶数量")
                        return@oneClick
                    }

                    type != 2 && type != 4 && totalMoney.isEmpty() -> {
                        this@showBucketDialog.shortToast("请输入押金金额")
                        return@oneClick
                    }
                }

                dismiss()

                onSure.invoke(amount, totalMoney)
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        return@setOnKeyListener conditionIf(
            express = keyCode == KeyEvent.KEYCODE_BACK,
            valueT = isForced,
            valueF = false
        )
    }
    dialog.setCanceledOnTouchOutside(!isForced)
    dialog.setOnDismissListener { onDismiss() }
    dialog.show()

    return dialog
}

/**
 * 报单商品编辑输入框
 */
fun Context.showManualDialog(
    name: String,
    price: String,
    defaultNum: String = "",
    priceEnable: Boolean = true,
    isForced: Boolean = false,
    onDismiss: () -> Unit = {},
    onCancel: () -> Unit = {},
    onSure: (String, String) -> Unit = { _, _ -> }
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(0.8f)
            val view = inflate<View>(R.layout.dialog_manual_input)

            val tvName = view.find<TextView>(R.id.dialog_name)
            val etPrice = view.find<EditText>(R.id.dialog_price)
            val etNum = view.find<EditText>(R.id.dialog_num)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            tvName.text = name
            etPrice.filters = arrayOf<InputFilter>(DecimalNumberFilter())

            priceEnable.conditionElse(
                actionTrue = {
                    etPrice.setText(price.formatDecimal())
                    etPrice.setSelection(etPrice.text.length)
                },
                actionFalse = {
                    etPrice.setText("${price.formatDecimal()} 元")
                    etPrice.isFocusableInTouchMode = false
                    etPrice.isFocusable = false
                }
            )

            defaultNum.notEmpty {
                etNum.setText(defaultNum)
                etNum.setSelection(etNum.text.length)
            }

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                val money = etPrice.content
                val amount = etNum.content

                when {
                    priceEnable && money.doubleValue <= 0 -> {
                        this@showManualDialog.shortToast("商品单价不能小于0")
                        return@oneClick
                    }

                    amount.intValue <= 0 -> {
                        this@showManualDialog.shortToast("商品数量不能小于0")
                        return@oneClick
                    }
                }

                dismiss()

                onSure.invoke(money, amount)
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        return@setOnKeyListener conditionIf(
            express = keyCode == KeyEvent.KEYCODE_BACK,
            valueT = isForced,
            valueF = false
        )
    }
    dialog.setCanceledOnTouchOutside(!isForced)
    dialog.setOnDismissListener { onDismiss() }
    dialog.show()

    return dialog
}

/**
 * 员工设置店铺列表
 */
fun Context.showShopDialog(
    items: List<MasterData>,
    onResult: (Int) -> Unit = { }
) {
    val dialog = BottomSheetDialog(this, R.style.BottomSheetDialogStyle)
    val view = inflate<View>(R.layout.dialog_record_show)

    view.find<TextView>(R.id.dialog_title).text = "请选择店铺"
    view.find<TextView>(R.id.dialog_cancle).oneClick { dialog.dismiss() }
    view.find<RecyclerView>(R.id.dialog_list).apply {
        loadLinear()
        addItemDecoration(DividerLRDecoration())

        adapter = SlimAdapter.creator()
            .register<MasterData>(R.layout.item_master_shop) { jector, bean, index ->
                jector.apply {
                    text(R.id.item_shop_name, bean.name)
                    text(R.id.item_shop_adress, bean.address)
                    text(R.id.item_shop_leader, bean.linkman)

                    visibility(
                        R.id.item_shop_right,
                        visibleValue { bean.check }
                    )

                    clicked {
                        items.forEach { it.check = false }
                        bean.check = true

                        dialog.dismiss()
                        onResult.invoke(index)
                    }
                }
            }
            .attachTo(this)

        (adapter as SlimAdapter).setDataList(items)
    }

    dialog.setContentView(view)

    // 默认是否展开
    BottomSheetBehavior
        .from(view.parent as View)
        .state = BottomSheetBehavior.STATE_COLLAPSED

    dialog.show()
}

/**
 * 显示我的二维码
 */
fun Context.showQrcodeDialog(
    name: String,
    logo: String,
    scale: Float = 0.75f,
    isForced: Boolean = false
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(scale)
            val view = inflate<View>(R.layout.dialog_qrcode_hint)

            val ivImg = view.find<ImageView>(R.id.dialog_img)
            val ivCode = view.find<ImageView>(R.id.dialog_qrcode)
            val tvName = view.find<TextView>(R.id.dialog_name)

            tvName.text = name
            ivImg.loadCircleImage(logo, R.mipmap.default_user)
            Flowable
                .just(
                    "${BuildConfig.API_HOST}/q/${QRMode.MODE_01.model}${getString("uid").intValue + 10200}.jhtml"
                )
                .map {
                    QRCodeEncoder
                        .syncEncodeQRCode(
                            it,
                            dp2px(180f),
                            Color.BLACK
                        )
                }
                .compose(applyFlowableSchedulers())
                .subscribe { ivCode.setImageBitmap(it) }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        return@setOnKeyListener (keyCode == KeyEvent.KEYCODE_BACK)
            .conditionElseValue(
                actionTrue = { isForced },
                actionFalse = { false }
            )
    }
    dialog.setCanceledOnTouchOutside(!isForced)
    dialog.show()

    return dialog
}

/**
 * 订单、商品改价
 */
fun Context.showPriceDialog(
    title: String = "温馨提示",
    hint: String = "",
    default: String = "",
    scale: Float = 0.75f,
    onCancel: () -> Unit = {},
    onSure: (String) -> Unit = {}
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(scale)
            val view = inflate<View>(R.layout.dialog_member_change)

            val tvTitle = view.find<TextView>(R.id.dialog_title)
            val tvName = view.find<TextView>(R.id.dialog_name)
            val llName = view.find<LinearLayout>(R.id.dialog_name_ll)
            val tvOrigin = view.find<TextView>(R.id.dialog_origin)
            val etNew = view.find<EditText>(R.id.dialog_new)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            tvTitle.text = title
            tvOrigin.text = default.formatDecimal()

            hint.notEmpty {
                llName.visible()
                tvName.text = hint
            }

            etNew.filters = arrayOf(DecimalNumberFilter())
            etNew.requestFocus()

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                val value = etNew.textTrim

                value.ifEmpty {
                    this@showPriceDialog.shortToast("请输入修改金额")
                    return@oneClick
                }

                dismiss()
                onSure.invoke(value)
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ -> keyCode == KeyEvent.KEYCODE_BACK }
    dialog.setCanceledOnTouchOutside(false)
    dialog.show()

    return dialog
}

/**
 * 修改昵称、备注、驳回原因、记账额度
 */
fun Context.showMemoDialog(
    title: String = "温馨提示",
    hint: String = "请输入内容",
    default: String = "",
    inputType: String,
    isForced: Boolean = false,
    canEmpty: Boolean = true,
    scale: Float = 0.75f,
    onCancel: () -> Unit = {},
    onSure: (String) -> Unit = {}
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(scale)
            val view = inflate<View>(R.layout.dialog_single_input)

            val tvTitle = view.find<TextView>(R.id.dialog_title)
            val etHint = view.find<EditText>(R.id.dialog_input)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            tvTitle.text = title
            etHint.hint = hint

            when (inputType) {
                "text" -> {
                    etHint.filters = arrayOf(NameLengthFilter(20))

                    default.notEmpty {
                        etHint.setText(this)
                        etHint.setSelection(etHint.text.length)
                    }
                }

                "longText" -> {
                    default.notEmpty {
                        etHint.setText(this)
                        etHint.setSelection(etHint.text.length)
                    }
                }

                "double" -> {
                    // 设置两位小数和输入最大长度
                    etHint.filters = arrayOf(DecimalNumberFilter(), NameLengthFilter(8))
                    // 设置输入方式
                    etHint.inputType =
                        InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
                    // 设置可输入字符
                    etHint.keyListener = DigitsKeyListener.getInstance("0123456789-.")

                    (default.doubleValue != 0.0)
                        .condition {
                            etHint.setText(default.formatDecimal())
                            etHint.setSelection(etHint.text.length)
                        }
                }

                "number" -> {
                    // 设置输入最大长度
                    etHint.filters = arrayOf(NameLengthFilter(5))
                    // 设置输入方式
                    etHint.inputType =
                        InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL
                    // 设置可输入字符
                    etHint.keyListener = DigitsKeyListener.getInstance("0123456789-")

                    (default.intValue != 0)
                        .condition {
                            etHint.setText(default)
                            etHint.setSelection(etHint.text.length)
                        }
                }
            }

            etHint.requestFocus()

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                val value = etHint.textTrim

                (value.isEmpty() && !canEmpty)
                    .condition {
                        this@showMemoDialog.shortToast(hint)
                        return@oneClick
                    }

                dismiss()
                onSure.invoke(value)
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        return@setOnKeyListener (keyCode == KeyEvent.KEYCODE_BACK)
            .conditionElseValue(
                actionTrue = { isForced },
                actionFalse = { false }
            )
    }
    dialog.setCanceledOnTouchOutside(!isForced)
    dialog.show()

    return dialog
}

/**
 * 工资结算弹框
 */
fun Context.showSalaryDialog(
    title: String = "工资结算",
    hint: String = "请输入结算金额",
    isForced: Boolean = false,
    onCancel: () -> Unit = {},
    onSure: (String) -> Unit = {}
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(0.75f)
            val view = inflate<View>(R.layout.dialog_salary_input)

            val tvTitle = view.find<TextView>(R.id.dialog_title)
            val etHint = view.find<EditText>(R.id.dialog_input)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            tvTitle.text = title
            etHint.hint = hint
            etHint.filters = arrayOf(DecimalNumberFilter())
            etHint.requestFocus()

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                val value = etHint.textTrim
                if (value.isEmpty()) {
                    this@showSalaryDialog.shortToast(hint)
                    return@oneClick
                }

                dismiss()
                onSure.invoke(value)
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        if (keyCode == KeyEvent.KEYCODE_BACK) return@setOnKeyListener isForced
        else return@setOnKeyListener false
    }
    dialog.setCanceledOnTouchOutside(!isForced)
    dialog.show()

    return dialog
}

/**
 * 记账统计平账弹框
 */
fun Context.showBillDialog(
    default: Double = 0.0,
    onSure: (String) -> Unit = {}
) {
    val dialog = BottomSheetDialog(this, R.style.BottomSheetDialogInput)
    val view = inflate<View>(R.layout.dialog_bill_input)
        .apply {
            val etInput = find<EditText>(R.id.dialog_input)
            etInput.filters = arrayOf(DecimalNumberFilter())

            find<ImageView>(R.id.dialog_close).oneClick { dialog.dismiss() }
            find<Button>(R.id.dialog_sure).oneClick {
                etInput.text
                    .ifEmpty {
                        shortToast("请输入还款金额")
                        return@oneClick
                    }

                dialog.dismiss()
                onSure.invoke(etInput.content)
            }

            etInput.requestFocus()

            (default > 0)
                .condition {
                    etInput.setText(default.formatDecimal())
                    etInput.setSelection(etInput.text.length)
                }
        }

    dialog.setContentView(view)

    // 默认是否展开
    BottomSheetBehavior
        .from(view.parent as View)
        .state = BottomSheetBehavior.STATE_EXPANDED

    dialog.show()
}

/**
 * 首次进入服务政策提示
 */
fun Context.showFirstDialog(
    onCancel: () -> Unit = {},
    onSure: () -> Unit = {}
) {
    val dialog = object : BaseDialog(this) {

        override fun onCreateView(): View {
            widthScale(0.8f)
            val view = inflate<View>(R.layout.dialog_first_hint)

            val tvHint = view.findViewById<TextView>(R.id.dialog_hint)
            val btCancel = view.findViewById<TextView>(R.id.dialog_cancel)
            val btSure = view.findViewById<TextView>(R.id.dialog_sure)

            // 去掉 ClickableSpan 点击后的背景色
            tvHint.highlightColor = getColorEx(R.color.transparent)

            TextDecorator
                .decorate(
                    tvHint,
                    getString(R.string.hint_first)
                )
                .setTextColor(R.color.colorAccent, "《服务协议》", "《隐私政策》")
                .makeTextClickable(
                    { _, text ->
                        when (text) {
                            "《服务协议》" -> startActivityEx<WebActivity>("title" to "用户协议")
                            "《隐私政策》" -> startActivityEx<WebActivity>("title" to "隐私政策")
                        }
                    },
                    false,
                    "《服务协议》", "《隐私政策》"
                )
                .build()

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                dismiss()
                onSure.invoke()
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ -> keyCode == KeyEvent.KEYCODE_BACK }
    dialog.setCanceledOnTouchOutside(false)
    dialog.show()
}

/**
 * 运单规划商品明细
 */
fun Context.showRouteDialog(
    orders: List<Any>,
    points: List<LatLngBean>,
    action: (Int) -> Unit = {}
) {
    val dialog = BottomSheetDialog(this, R.style.BottomSheetDialogStyle)
    val view = inflate<View>(R.layout.dialog_deliver_detail)

    view.find<RecyclerView>(R.id.dialog_list).apply {
        loadLinear()
        addItemDecoration(SpaceTBDecoration(hasHeader = false))

        adapter = SlimAdapter.creator()
            .register<LatLngBean>(R.layout.item_route_list) { jector, bean, index ->

                val orderItem = orders[bean.orderIndex] as OrderData

                jector.apply {
                    text(R.id.item_route_code, (index + 1).toString())
                    text(R.id.item_route_name, orderItem.consignee.orEmpty())
                    text(
                        R.id.item_route_phone,
                        when {
                            userRole in "1,2"
                                    || privacyStatus == "off" -> orderItem.phone.orEmpty()

                            else -> orderItem.phone.phoneReplaceWithStar()
                        }

                    )
                    text(R.id.item_route_distance, bean.distance.formatDistance())

                    with<LinearLayout>(R.id.item_route_goods) { layout ->
                        layout.removeAllViews()

                        orderItem.shippingItems.forEach {
                            layout.addView(
                                inflate<View>(R.layout.content_deliver_route_hint)
                                    .apply {
                                        find<TextView>(R.id.conent_title).text = it.name
                                        find<TextView>(R.id.conent_num).text = it.quantity
                                    }
                            )
                        }
                    }

                    clicked {
                        action(bean.orderIndex)

                        startActivityEx<DeliverDetailActivity>(
                            "orderSn" to orderItem.orderSn,
                            "shippingSn" to orderItem.sn,
                            "status" to "dispatch",
                            "shipId" to orderItem.id
                        )
                    }
                }
            }
            .attachTo(this)

        (adapter as SlimAdapter).setDataList(points)
    }

    dialog.setContentView(view)

    // 默认是否展开
    BottomSheetBehavior
        .from(view.parent as View)
        .state = BottomSheetBehavior.STATE_COLLAPSED

    dialog.show()
}

/**
 * 员工区域编辑弹框
 */
fun Context.showBottomAreaDialog(
    hint: String = "",
    isForced: Boolean = false,
    onSelect: (Int) -> Unit
) {

    val dialog = object : BottomDialog(this) {

        override fun onCreateView(): View {
            val view = inflate<View>(R.layout.dialog_master_area_edit)

            val llChange = view.findViewById<LinearLayout>(R.id.dialog_change)
            val tvName = view.findViewById<TextView>(R.id.dialog_hint)
            val tvModify = view.findViewById<TextView>(R.id.dialog_modify)
            val tvDelete = view.findViewById<TextView>(R.id.dialog_delete)
            val tvCancel = view.findViewById<TextView>(R.id.dialog_cancel)

            tvName.text = hint

            llChange.oneClick {
                dismiss()
                onSelect.invoke(0)
            }

            tvModify.oneClick {
                dismiss()
                onSelect.invoke(1)
            }

            tvDelete.oneClick {
                dismiss()
                onSelect.invoke(2)
            }

            tvCancel.oneClick {
                dismiss()
            }

            return view
        }

    }

    dialog.setCanceledOnTouchOutside(!isForced)
    dialog.show()

    dialog.window
        ?.attributes = dialog.window?.attributes.apply {
        this?.width = getScreenWidth() //设置宽度
    }
}

/**
 * 订单详情物流明细
 */
fun Context.showOrderLogDialog(items: List<OrderLogData>) {
    val dialog = BottomSheetDialog(this, R.style.BottomSheetDialogStyle)
    val view = inflate<View>(R.layout.dialog_order_detail_log)

    view.find<RecyclerView>(R.id.dialog_log_list).apply {
        loadLinear()

        adapter = SlimAdapter.creator()
            .register<OrderLogData>(R.layout.item_order_log) { jector, bean, index ->
                jector.apply {
                    text(R.id.item_log_hint1, bean.createDate.getTimeString())
                    text(R.id.item_log_hint2, bean.content)

                    image(
                        R.id.item_log_ova,
                        conditionIf(
                            index == 0,
                            R.drawable.ova_coloraccent,
                            R.drawable.ova_light
                        )
                    )

                    visibility(
                        R.id.item_log_divider1,
                        invisibleValue { index == 0 }
                    )

                    visibility(
                        R.id.item_log_divider2,
                        invisibleValue { index == items.size - 1 }
                    )
                }
            }
            .attachTo(this)

        (adapter as SlimAdapter).setDataList(items)
    }

    view.find<View>(R.id.dialog_log_close)
        .oneClick { dialog.dismiss() }

    dialog.setContentView(view)

    // 默认是否展开
    BottomSheetBehavior
        .from(view.parent as View)
        .state = BottomSheetBehavior.STATE_COLLAPSED

    dialog.show()
}

/**
 * 自提柜添加和修改弹框
 */
fun Context.showCupboardDialog(
    defName: String = "",
    defCode: String = "",
    defStatus: String = "",
    defCount: String = "",
    defNum: String = "",
    defTypeId: String = "AIR_BASIC",
    defTypeName: String = "云柜-普通版",
    isForced: Boolean = false,
    onDismiss: () -> Unit = {},
    onScan: (EditText) -> Unit = { _ -> },
    onSelect: (TextView, View, View, Array<String>) -> Unit = { _, _, _, _ -> },
    onStatus: (TextView, Array<String>) -> Unit = { _, _ -> },
    onCancel: () -> Unit = {},
    onSure: (String, String, String, String, String, String) -> Unit = { _, _, _, _, _, _ -> }
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(0.8f)
            val view = inflate<View>(R.layout.dialog_pickup_cupboard)

            val etName = view.find<EditText>(R.id.dialog_name)
            val etCode = view.find<EditText>(R.id.dialog_code)
            val etTotal = view.find<EditText>(R.id.dialog_total)
            val etScreen = view.find<EditText>(R.id.dialog_screen)
            val ivScan = view.find<ImageView>(R.id.dialog_scan)
            val tvType = view.find<TextView>(R.id.dialog_type)
            val llType = view.find<LinearLayout>(R.id.dialog_type_ll)
            val tvStatus = view.find<TextView>(R.id.dialog_status)
            val llTotal = view.find<LinearLayout>(R.id.dialog_total_ll)
            val llScreen = view.find<LinearLayout>(R.id.dialog_screen_ll)
            val llStatus = view.find<LinearLayout>(R.id.dialog_status_ll)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            // 设备名称
            defName.notEmpty {
                etName.setText(this)
                etName.setSelection(etName.text.length)
            }

            // 设备编号
            defCode.notEmpty {
                etCode.setText(this)
            }

            // 柜子数量
            defCount.notEmpty {
                etTotal.setText(this)
            }

            // 屏幕编号
            defNum.notEmpty {
                etScreen.setText(this)
            }

            // 设备状态
            val statusArr = arrayOf(
                defStatus,
                when (defStatus) {
                    "online" -> "在线"
                    "stop" -> "停用"
                    else -> "离线"
                }
            )
            tvStatus.text = statusArr[1]
            llStatus.isVisible = statusArr[0].isNotEmpty()

            // 设备类型
            val typeArr = arrayOf(defTypeId, defTypeName)
            llTotal.isVisible = "_EXTEND" in typeArr[0]
            llScreen.isVisible = typeArr[0] in "AIR_TOUCh_EXTEND"
            tvType.text = typeArr[1]


            ivScan.oneClick {
                onScan.invoke(etCode)
            }

            llType.oneClick {
                onSelect.invoke(tvType, llTotal, llScreen, typeArr)
            }

            llStatus.oneClick {
                onStatus.invoke(tvStatus, statusArr)
            }

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                val inName = etName.textTrim
                val inCode = etCode.textTrim
                var inCount = etTotal.content
                var inScreen = etScreen.content

                when {
                    inName.isEmpty() -> {
                        this@showCupboardDialog.shortToast("请输入设备名称")
                        return@oneClick
                    }

                    inCode.isEmpty() -> {
                        this@showCupboardDialog.shortToast("请输入设备编号")
                        return@oneClick
                    }

                    typeArr[0].isEmpty() -> {
                        this@showCupboardDialog.shortToast("请选择设备类型")
                        return@oneClick
                    }

                    llTotal.isVisible && inCount.isEmpty() -> {
                        this@showCupboardDialog.shortToast("请输入主副柜总数")
                        return@oneClick
                    }

                    llStatus.isVisible && statusArr[0].isEmpty() -> {
                        this@showCupboardDialog.shortToast("请选择设备状态")
                        return@oneClick
                    }
                }

                llTotal.isGone.condition { inCount = "1" }
                llScreen.isGone.condition { inScreen = "" }

                dismiss()
                onSure.invoke(inName, inCode, typeArr[0], inCount, inScreen, statusArr[0])
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        return@setOnKeyListener (keyCode == KeyEvent.KEYCODE_BACK)
            .conditionElseValue(
                actionTrue = { isForced },
                actionFalse = { false }
            )
    }
    dialog.setCanceledOnTouchOutside(!isForced)
    dialog.setOnDismissListener { onDismiss() }
    dialog.show()

    return dialog
}

/**
 * 自提柜商品编辑
 */
fun Context.showCupboardItemDialog(
    item: CupboardCodeData,
    index: Int,
    isForced: Boolean = false,
    onDismiss: () -> Unit = {},
    onCancel: () -> Unit = {},
    onSelect: (TextView, TextView, ArrayList<String>) -> Unit = { _, _, _ -> },
    onSure: (ArrayList<String>) -> Unit = {}
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(0.8f)
            val view = inflate<View>(R.layout.dialog_cupboard_input)

            val llSelect = view.find<LinearLayout>(R.id.dialog_select)
            val tvName = view.find<TextView>(R.id.dialog_name)
            val tvPrice = view.find<TextView>(R.id.dialog_price)
            val etPeriod = view.find<EditText>(R.id.dialog_period)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            tvName.text = item.productName.orEmpty()
            tvPrice.text = item.price.formatDecimal()

            item.period.notEmpty {
                etPeriod.setText(this)
                etPeriod.setSelection(etPeriod.text.length)
            }

            val dataList = arrayListOf(
                item.no,
                item.stock,
                item.stockId.orEmpty(),
                item.thumbnail.orEmpty(),
                item.productName.orEmpty(),
                item.period.orEmpty(),
                index.toString()
            )

            llSelect.oneClick {
                onSelect.invoke(tvName, tvPrice, dataList)
            }

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                val amount = etPeriod.content

                when {
                    amount.intValue <= 0 -> {
                        this@showCupboardItemDialog.shortToast("商品保质期不能小于0")
                        return@oneClick
                    }
                }

                dataList[5] = amount

                dismiss()

                onSure.invoke(dataList)
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        return@setOnKeyListener conditionIf(
            express = keyCode == KeyEvent.KEYCODE_BACK,
            valueT = isForced,
            valueF = false
        )
    }
    dialog.setCanceledOnTouchOutside(!isForced)
    dialog.setOnDismissListener { onDismiss() }
    dialog.show()

    return dialog
}

/**
 * 进销存库存弹框
 */
fun Context.showStockDialog(
    name: String,
    type: Int = 1,
    isForced: Boolean = false,
    onDismiss: () -> Unit = {},
    onSelect: (TextView, Array<String>) -> Unit = { _, _ -> },
    onCancel: () -> Unit = {},
    onSure: (String, String, String) -> Unit = { _, _, _ -> }
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(0.8f)
            val view = inflate<View>(R.layout.dialog_stock_input)

            val llSelect = view.find<LinearLayout>(R.id.dialog_select)
            val tvTitle = view.find<TextView>(R.id.dialog_title)
            val tvName = view.find<TextView>(R.id.dialog_name)
            val tvReason = view.find<TextView>(R.id.dialog_reason)
            val etNum = view.find<EditText>(R.id.dialog_num)
            val etMemo = view.find<EditText>(R.id.dialog_memo)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            when (type) {
                1 -> tvTitle.text = "增加库存"
                2 -> tvTitle.text = "减少库存"
            }
            tvName.text = name
            val reasonArr = arrayOf("")

            llSelect.oneClick {
                onSelect.invoke(tvReason, reasonArr)
            }

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                val amount = etNum.content
                val memo = etMemo.content

                when {
                    reasonArr[0].isEmpty() -> {
                        this@showStockDialog.shortToast("请选择事由")
                        return@oneClick
                    }

                    amount.isEmpty() -> {
                        this@showStockDialog.shortToast("请输入数量")
                        return@oneClick
                    }
                }

                dismiss()

                onSure.invoke(reasonArr[0], amount, memo)
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        return@setOnKeyListener conditionIf(
            express = keyCode == KeyEvent.KEYCODE_BACK,
            valueT = isForced,
            valueF = false
        )
    }
    dialog.setCanceledOnTouchOutside(!isForced)
    dialog.setOnDismissListener { onDismiss() }
    dialog.show()

    return dialog
}

/**
 * 进销存供应商欠款弹框
 */
fun Context.showSupplyMoneyDialog(
    name: String,
    type: Int = 1,
    onDismiss: () -> Unit = {},
    onCancel: () -> Unit = {},
    onSure: (String, String) -> Unit = { _, _ -> }
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(0.8f)
            val view = inflate<View>(R.layout.dialog_supply_money_input)

            val tvTitle = view.find<TextView>(R.id.dialog_title)
            val tvName = view.find<TextView>(R.id.dialog_name)
            val etNum = view.find<EditText>(R.id.dialog_num)
            val etMemo = view.find<EditText>(R.id.dialog_memo)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            when (type) {
                1 -> tvTitle.text = "增加欠款"
                2 -> tvTitle.text = "减少欠款"
            }
            tvName.text = name
            etNum.filters = arrayOf(DecimalNumberFilter(), NameLengthFilter(10))

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                val amount = etNum.content
                val memo = etMemo.content

                when {
                    amount.isEmpty() -> {
                        this@showSupplyMoneyDialog.shortToast("请输入修改金额")
                        return@oneClick
                    }
                }

                dismiss()

                onSure.invoke(amount, memo)
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        return@setOnKeyListener keyCode == KeyEvent.KEYCODE_BACK
    }
    dialog.setCanceledOnTouchOutside(false)
    dialog.setOnDismissListener { onDismiss() }
    dialog.show()

    return dialog
}

/**
 * 进销存供应商欠桶弹框
 */
fun Context.showSupplyBarrelDialog(
    name: String,
    type: Int = 1,
    onDismiss: () -> Unit = {},
    onSelect: (TextView, Array<String>) -> Unit = { _, _ -> },
    onCancel: () -> Unit = {},
    onSure: (String, String, String) -> Unit = { _, _, _ -> }
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(0.8f)
            val view = inflate<View>(R.layout.dialog_supply_barrel_input)

            val llSelect = view.find<LinearLayout>(R.id.dialog_select)
            val tvTitle = view.find<TextView>(R.id.dialog_title)
            val tvName = view.find<TextView>(R.id.dialog_name)
            val tvBarrel = view.find<TextView>(R.id.dialog_barrel)
            val etNum = view.find<EditText>(R.id.dialog_num)
            val etMemo = view.find<EditText>(R.id.dialog_memo)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            when (type) {
                1 -> tvTitle.text = "增加欠桶"
                2 -> tvTitle.text = "减少库存"
            }
            tvName.text = name
            val barrelArr = arrayOf("")

            llSelect.oneClick {
                onSelect.invoke(tvBarrel, barrelArr)
            }

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                val amount = etNum.content
                val memo = etMemo.content

                when {
                    barrelArr[0].isEmpty() -> {
                        this@showSupplyBarrelDialog.shortToast("请选择品牌类型")
                        return@oneClick
                    }

                    amount.isEmpty() -> {
                        this@showSupplyBarrelDialog.shortToast("请输入修改数量")
                        return@oneClick
                    }
                }

                dismiss()

                onSure.invoke(barrelArr[0], amount, memo)
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        return@setOnKeyListener keyCode == KeyEvent.KEYCODE_BACK
    }
    dialog.setCanceledOnTouchOutside(false)
    dialog.setOnDismissListener { onDismiss() }
    dialog.show()

    return dialog
}

/**
 * 休眠会员更多操作
 */
fun Context.showOfflineWindow(
    anchor: View,
    isEdit: Boolean,
    onSelect: (Int) -> Unit = {}
): BasePopup {

    val popup = object : BasePopup(this) {

        override fun onCreatePopupView(): View {
            val view = inflate<View>(R.layout.pop_edit_offline)

            view.find<TextView>(R.id.pop_more)
                .text = conditionIf(
                isEdit,
                "取消批量",
                "批量提醒"
            )

            view.find<LinearLayout>(R.id.pop_more_ll)
                .oneClick {
                    onSelect.invoke(0)
                    dismiss()
                }
            view.find<LinearLayout>(R.id.pop_shop_ll)
                .oneClick {
                    onSelect.invoke(1)
                    dismiss()
                }

            return view
        }

    }

    popup.anchorView(anchor)
        .gravity(Gravity.BOTTOM)
        .showAnim(FadeEnter().apply { duration(250) })
        .dismissAnim(FadeExit().apply { duration(250) })
        .dimEnabled(false)
        .offset(-10f, -10f)
        .show()

    return popup
}

/**
 * 自提站点更多操作
 */
fun Context.showPickupWindow(
    anchor: View,
    onSelect: (Int) -> Unit = {}
): BasePopup {

    val popup = object : BasePopup(this) {

        override fun onCreatePopupView(): View {
            val view = inflate<View>(R.layout.pop_menu_pickup)

            view.find<TextView>(R.id.pop_category)
                .oneClick {
                    onSelect.invoke(0)
                    dismiss()
                }

            view.find<TextView>(R.id.pop_sale)
                .oneClick {
                    onSelect.invoke(1)
                    dismiss()
                }
            view.find<TextView>(R.id.pop_order)
                .oneClick {
                    onSelect.invoke(2)
                    dismiss()
                }

            return view
        }

    }

    popup.anchorView(anchor)
        .gravity(Gravity.BOTTOM)
        .showAnim(FadeEnter().apply { duration(250) })
        .dismissAnim(FadeExit().apply { duration(250) })
        .dimEnabled(false)
        .offset(-10f, -10f)
        .show()

    return popup
}

/**
 * 批量发货提示框
 */
fun Context.showBatchSendDialog(
    title: String = "批量发货",
    shopId: String = "",
    shopName: String = "",
    isForced: Boolean = false,
    onDismiss: () -> Unit = {},
    onShop: (TextView, Array<String>) -> Unit = { _, _ -> },
    onAdmin: (TextView, Array<String>, Array<String>) -> Unit = { _, _, _ -> },
    onCancel: () -> Unit = {},
    onSure: (String, String, String) -> Unit = { _, _, _ -> }
): BaseDialog {
    val dialog = object : BaseDialog(this, true) {

        override fun onCreateView(): View {
            widthScale(0.8f)
            val view = inflate<View>(R.layout.dialog_batch_send)

            val llWhere = view.find<LinearLayout>(R.id.dialog_where_ll)
            val llWho = view.find<LinearLayout>(R.id.dialog_who_ll)
            val tvTitle = view.find<TextView>(R.id.dialog_title)
            val tvWhere = view.find<TextView>(R.id.dialog_where)
            val tvWho = view.find<TextView>(R.id.dialog_who)
            val etMemo = view.find<EditText>(R.id.dialog_memo)
            val btCancel = view.find<TextView>(R.id.dialog_cancel)
            val btSure = view.find<TextView>(R.id.dialog_sure)

            tvTitle.text = title

            val mShopArray = arrayOf(shopId)
            val mAdminArray = arrayOf("")
            shopName.notEmpty {
                tvWhere.text = this
            }

            llWhere.oneClick { onShop.invoke(tvWhere, mShopArray) }
            llWho.oneClick {
                mShopArray[0]
                    .isEmpty()
                    .condition {
                        this@showBatchSendDialog.shortToast("请选择配送仓库")
                        return@oneClick
                    }

                onAdmin.invoke(tvWho, mShopArray, mAdminArray)
            }

            btCancel.oneClick {
                dismiss()
                onCancel.invoke()
            }

            btSure.oneClick {
                when {
                    mShopArray[0].isEmpty() -> {
                        this@showBatchSendDialog.shortToast("请选择配送仓库")
                        return@oneClick
                    }

                    mAdminArray[0].isEmpty() -> {
                        this@showBatchSendDialog.shortToast("请选择送货人员")
                        return@oneClick
                    }
                }

                dismiss()
                onSure.invoke(
                    mShopArray[0],
                    mAdminArray[0],
                    etMemo.textTrim
                )
            }

            return view
        }
    }

    dialog.setOnKeyListener { _, keyCode, _ ->
        return@setOnKeyListener conditionIf(
            express = keyCode == KeyEvent.KEYCODE_BACK,
            valueT = isForced,
            valueF = false
        )
    }
    dialog.setCanceledOnTouchOutside(!isForced)
    dialog.setOnDismissListener { onDismiss() }
    dialog.show()

    return dialog
}

fun Context.showAreaDialog(
    title: String = "请选择",
    list: List<RegionBean> = ArrayList(),
    listener: (String, String, String, String, String, String) -> Unit = { _, _, _, _, _, _ -> }
) {
    val dialog = object : BottomDialog(this) {

        private lateinit var loopProvince: LoopView
        private lateinit var loopCity: LoopView
        private lateinit var loopArea: LoopView

        override fun onCreateView(): View {
            val view = inflate<View>(R.layout.dialog_select_area)

            loopProvince =
                view.find<LoopView>(R.id.dialog_lv_province)
                    .apply {
                        setTextSize(14f)
                        setDividerColor(getColorEx(R.color.divider))
                        setNotLoop()
                    }

            loopCity =
                view.find<LoopView>(R.id.dialog_lv_city)
                    .apply {
                        setTextSize(14f)
                        setDividerColor(getColorEx(R.color.divider))
                        setNotLoop()
                    }

            loopArea =
                view.find<LoopView>(R.id.dialog_lv_area)
                    .apply {
                        setTextSize(14f)
                        setDividerColor(getColorEx(R.color.divider))
                        setNotLoop()
                    }

            val tvTitle = view.findViewById<TextView>(R.id.dialog_title)
            val tvCancel = view.findViewById<TextView>(R.id.dialog_cancle)
            val tvSure = view.findViewById<TextView>(R.id.dialog_sure)

            tvTitle.text = title

            tvCancel.oneClick { dismiss() }

            tvSure.oneClick {
                val indexProvince = loopProvince.selectedItem
                val indexCity = loopCity.selectedItem
                val indexArea = loopArea.selectedItem

                val provinceName = list[indexProvince].name
                val cityName = list[indexProvince].children[indexCity].name
                val areaName = list[indexProvince].children[indexCity].children[indexArea].name

                val provinceCode = list[indexProvince].code
                val cityCode = list[indexProvince].children[indexCity].code
                val areaCode = list[indexProvince].children[indexCity].children[indexArea].code

                dismiss()
                listener.invoke(
                    provinceName,
                    cityName,
                    areaName,
                    provinceCode,
                    cityCode,
                    areaCode
                )
            }

            return view
        }

        override fun setUiBeforShow() {
            val listProvince = ArrayList<String>()
            val listCity = ArrayList<String>()
            val listArea = ArrayList<String>()

            list.mapTo(listProvince) { it.name }
            list[0].children.mapTo(listCity) { it.name }
            list[0].children[0].children.mapTo(listArea) { it.name }

            loopProvince.setItems(listProvince)
            loopCity.setItems(listCity)
            loopArea.setItems(listArea)

            loopCity.setOnItemSelectedListener {
                val index1 = loopProvince.selectedItem
                val index2 = loopCity.selectedItem

                listArea.clear()
                list[index1].children[index2].children.mapTo(listArea) { it.name }

                loopArea.setItems(listArea)

                loopArea.setCurrentPosition(0)
            }

            loopProvince.setOnItemSelectedListener {
                val index = loopProvince.selectedItem

                listCity.clear()
                listArea.clear()

                list[index].children.mapTo(listCity) { it.name }
                list[index].children[0].children.mapTo(listArea) { it.name }

                loopCity.setItems(listCity)
                loopArea.setItems(listArea)

                loopCity.setCurrentPosition(0)
                loopArea.setCurrentPosition(0)
            }
        }

    }

    dialog.show()
}